Tensorflow lite在Android端部署

您所在的位置:网站首页 patotso lite安卓 Tensorflow lite在Android端部署

Tensorflow lite在Android端部署

2024-01-09 15:15| 来源: 网络整理| 查看: 265

最近一个项目需要使用Tensorflow lite, 官网上的解释又特别简单,主要给了一个例子,但是这个例子和官网的解释又不一样。。。。这里简单记录下操作方法。

添加依赖

某些加载的方法,依赖并不支持。

在自己的build.grandle的依赖中添加:

implementation 'org.tensorflow:tensorflow-lite:1.15.0' implementation 'org.tensorflow:proto:1.15.0' 模型转化

对于keras或者用model建立的模型,有直接的转化函数,对于sess建立的模型(计算图),有很多方法不再适用。我尝试了一种是可以使用的:

先转化为saved model通过saved model 转化为tflite file

转化为saved model:

tf.saved_model.simple_save( sess, "%s/trained model/flows" % (savedir), inputs={"input": input}, outputs={"flows": flows} )

注意:其中的inputs和outputs必须是张量,否则会提醒你array没有name属性。

inputs就是feed_dict中那些place holder,outputs可以填输出的张量,也可以直接填操作本身。

转为tflite file:

import tensorflow as tf converter = tf.lite.TFLiteConverter.from_saved_model(path) tflite_model = converter.convert() open(path+"/converted_model.tflite", "wb").write(tflite_model)

至此得到了tflite文件

模型加载

注意点: 1: 读取文件时需要申请权限 2: 对于Interpreter的构造函数,只有MappedByteBuffer那个可以使用,用File的那个会报错。

直接把生成的文件放在“我的手机”中,如果是虚拟机,则是storage/emulated/0文件夹下,然后使用

Environment.getExternalStorageDirectory().getPath();

后面加上文件名称,可以得到该文件的路径。

文件加载函数:

public MappedByteBuffer getFile(String fileName) throws IOException { File f = new File(fileName); FileInputStream in = new FileInputStream(f); FileChannel channel = in.getChannel(); return channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size()); }

把该函数返回的作为Interpreter的输入,可以生成一个解释器。

权限申请:

在manifest中增加:

对于Android11以下的版本,需要额外增加:

android:requestLegacyExternalStorage="true"

申请权限:

// Storage Permissions private static final int REQUEST_EXTERNAL_STORAGE = 1; private static String[] PERMISSIONS_STORAGE = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE }; public static void verifyStoragePermissions(Activity activity) { // Check if we have write permission int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE); if (permission != PackageManager.PERMISSION_GRANTED) { // We don't have permission so prompt the user ActivityCompat.requestPermissions( activity, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE ); } } 推理

有两个函数可以使用:

单输入输出 interpreter.run(inputs, outputs);

inputs和ouputs都是高维数组,比如正常的都是:

float[][][][] inputs = new float[1][h][w][3];

注意不管是输入还是输出,数组申请空间时候必须把每一个维度都确定,否则可能导致拷贝出错或者维度出错。

比如:

Caused by: java.lang.IllegalStateException: Internal error: Unexpected failure when preparing tensor allocations: tensorflow/lite/kernels/concatenation.cc:74 t->dims->data[d] != t0->dims->data[d] (1 != 2) Node number 9 (CONCATENATION) failed to prepare.

输入维度错误,或者没有给定输入的维度

ouputs也是多维数组,和inputs相同。

多输入 interpreter.runForMultipleInputsOutputs([Objects], outputs)

第一个参数是一个数组,里面是输入的张量。我猜测顺序和convert函数中命名的字典序有关。如果不放心的话,可以使用:

Tensor a = interpreter.getInputTensor(0);

然后看一下copyShape是否符合。

因此,如果张量是4维的,那么第一个参数是一个5维的数组。

outputs是一个Map,可以声明如下:

Map outputs = HashMap(); outputs.put(0,Objects); 其他

将Bitmap转为float数组:

public Bitmap toBitmap(float[][][] a){ int[] colors = new int[h_res*w_res]; for(int i = 0; i int r = (int)(a[j][i][0]*255) & 0xff; int g = (int)(a[j][i][1]*255) & 0xff; int b = (int)(a[j][i][2]*255) & 0xff; colors[i*h_res+j] = 0xff000000 | (r for (int j = 0; j


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3